#include <avr/io.h>
#include <avr/interrupt.h>


static volatile uint16_t TickCounter;
static volatile uint8_t TickCorrector;



#if defined (__AVR_ATmega16__)

static volatile uint8_t BeepDivider=0xFF;
static volatile uint8_t BeepDividerCounter=0x0;
static volatile uint8_t BeepLastPortValue=0x0;
#define BEEPIO 3 /* PA3 */


#endif




void TickcountPrepare(void)
{
	TickCorrector=0;
	TickCounter=0;

	TIMSK|=(1<<TOV0);
	TCNT0=0x00;
	

	#if defined (__AVR_ATmega8__)
	/* run at 14.7456MHz */

		TCCR0=3; //  prescale = 64
		/* this give 230.4kHz/256= tick every 1.11mS, about +7sek/min*/

	#elif defined (__AVR_ATmega16__)
	/* run at 8MHz */

		TCCR0=2; //  prescale = 8
		/* this give 1MHz/256= tick every 256uS, correct this in ISR */

		/* setup beeper */
		DDRA |= (1 << BEEPIO);	// set to output
		PORTA &= ~(1 << BEEPIO);

	#endif
}



uint16_t GetTickCount(void)
{
	uint16_t tc;

	cli();
		tc=TickCounter;
	sei();

	return tc;
}



uint16_t GetTickSince(uint16_t startTime)
{
 uint16_t endTime=GetTickCount();

	if (startTime > endTime)
	{
		return (0xFFFF - startTime + 1 + endTime);
	}
	else
	{
		return (endTime - startTime);
	}
}



ISR(TIMER0_OVF_vect)
{

	#if defined (__AVR_ATmega8__)

		TickCounter++;

	#elif defined (__AVR_ATmega16__)

		if(TickCorrector>=3)
		{
			TickCounter++;
			TickCorrector=0;

		} else
		{
			TickCorrector++;
		}


		if(BeepDivider>10)
		{
			PORTA &= ~(1 << BEEPIO);
		} else
		{
			if(BeepDividerCounter==0)
			{

				if(BeepLastPortValue)
				{
					PORTA &= ~(1 << BEEPIO);
					BeepLastPortValue=0;
				}
				 else
				{

					PORTA |= (1 << BEEPIO);
					BeepLastPortValue=1;
				}
			} 
			
			if((++BeepDividerCounter)>BeepDivider) BeepDividerCounter=0;
			
		}


	#endif
}


void Beep(unsigned char Tone)
{

	#if defined (__AVR_ATmega16__)

	cli();
	BeepDivider=Tone;
	BeepDividerCounter=0;
	sei();

	#endif
}



